//
// Created by Snow on 2023/5/22.
//
//最低位优先的基数排序算法
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define MAXE 20//线性表中最多元素个数
#define MAXR 10//基数的最大取值
#define MAXD 8//关键字位数的最大取值
typedef struct node
{
    char data[MAXD];//记录的关键字定义的字符串
    struct node *next;//指向下一个结点
}NodeType;//基数排序数据的结点类型

//单链表部分运算
void CreateLink(NodeType *&p,char a[MAXE][MAXD],int n)//采用后插法产生链表
{
    int i;
    NodeType *s,*t;
    for(i=0;i<n;i++)
    {
        s=(NodeType*)malloc(sizeof(NodeType));
        strcpy(s->data,a[i]);
        if(i==0)
        {
            p=s;
            t=s;
        }
        else
        {
            t->next=s;
            t=s;
        }
    }
    t->next=nullptr;
}
void DispLink(NodeType *p,int d)//输出链表
{
    int i;
    while(p!=nullptr)
    {
        for(i=d-1;i>=0;i--)
            printf("%c",p->data[i]);
        printf(" ");
        p=p->next;
    }
    printf("\n");
}

//LSD基数排序算法
void RadixSort(NodeType *&p,int r,int d)//实现基数排序：p为待排序序列链表指针，r为基数，d为关键字位数
{
    NodeType *head[MAXR],*tail[MAXR],*t;//定义各链队的首、尾指针
    int i,j,k;
    for(i=0;i<=d-1;i++)//从低位到高位循环
    {
        for(j=0;j<r;j++)//初始化各链队的首、尾指针
            head[j]=tail[j]=nullptr;
        while(p!=nullptr)//分配：对于原链表中的每个结点循环
        {
            k=p->data[i]-'0';//找第k个链队
            if(head[k]==nullptr)//第k个链队为空时，队头、队尾均指向结点p
            {
                head[k]=p;
                tail[k]=p;
            }
            else//第k个链队非空时结点p进队
            {
                tail[k]->next=p;
                tail[k]=p;
            }
            p=p->next;//取下一个待排序的元素
        }
        p=nullptr;//重新用p来收集所有结点
        for(j=0;j<r;j++)//收集：对于每个链队循环
            if(head[j]!=nullptr)//若第j个链队是第一个非空链队
            {
                if(p==nullptr)
                {
                    p=head[j];
                    t=tail[j];
                }
                else//若第j个链队是其他非空链队
                {
                    t->next=head[j];
                    t=tail[j];
                }
            }
        t->next=nullptr;//最后一个结点的next域置nullptr
    }
}
int main()
{
    int n=10,r=10,d=4;
    int i,j,k;
    NodeType *p;
    char a[MAXE][MAXD];
    int b[]={75,23,98,44,57,1222,129,64,38,82};
    for (i=0;i<n;i++)		//将b[i]转换成字符串
    {
        k=b[i];
        for(j=0;j<d;j++)	//例如b[0]=75,转换后a[0][0]='7',a[0][1]='5'
        {
            a[i][j]=k%10+'0';
            k=k/10;
        }
        a[i][j]='\0';
    }
    CreateLink(p,a,n);
    printf("\n");
    DispLink(p,d);
    RadixSort(p,r,d);
    DispLink(p,d);
    printf("\n");
}